package cn.xk.ymcc.service.impl;


import cn.xk.ymcc.domain.Login;
import cn.xk.ymcc.domain.User;
import cn.xk.ymcc.domain.UserAccount;
import cn.xk.ymcc.domain.UserBaseInfo;
import cn.xk.ymcc.dto.UserDto;
import cn.xk.ymcc.feign.UaaFeignClient;
import cn.xk.ymcc.mapper.UserAccountMapper;
import cn.xk.ymcc.mapper.UserBaseInfoMapper;
import cn.xk.ymcc.mapper.UserMapper;
import cn.xk.ymcc.result.JSONResult;
import cn.xk.ymcc.service.IUserService;
import cn.xk.ymcc.util.AssertUtil;
import cn.xk.ymcc.util.BitStatesUtils;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import io.seata.spring.annotation.GlobalTransactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;

/**
 * <p>
 * 会员登录账号 服务实现类
 * </p>
 *
 * @author 64009120@qq.com
 * @since 2023-03-10
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private RedisTemplate<Object, Object> redisTemplate;
    @Autowired
    private UaaFeignClient uaaFeignClient;
    @Autowired
    private UserAccountMapper userAccountMapper;
    @Autowired
    private UserBaseInfoMapper baseInfoMapper;

    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    public void register(UserDto userDto) {
        //1.校验验证码是否正确
        checkVerifyCode(userDto);
        //2.使用openfeign 发起远程调用--》保存t_login对象，返回新增数据的id主键
        Long loginId = createLogin(userDto);
        //3.生成t_user的数据【关联t_login的id】
        Long userId = createUser(userDto, loginId);
        //4.生成t_user_account 表数据 【使用t_user的id】
        createUserAccount(userId);
        //5.生成t_user_base_info表数据【使用t_user的id】
        createUserBaseInfo(userId, userDto.getRegChannel());

    }



    private Long createLogin(UserDto userDto) { //2.使用openfeign 发起远程调用--》保存t_login对象，返回新增数据的id主键
        Login login = new Login();
        login.setUsername(userDto.getMobile());
        login.setPassword(userDto.getPassword());//ToDo 后期要加密
        login.setType(Login.LOGIN_WEB);//设置为管理端
        JSONResult jsonResult = uaaFeignClient.register(login);
        //判断接口调用是否成功
        AssertUtil.isTrue(jsonResult.isSuccess(), jsonResult.getMessage());
        //数据强转
        Long loginid = Long.valueOf(jsonResult.getData().toString());
        return loginid;
    }

    private Long createUser(UserDto userDto, Long loginid) {
        //3.生成t_user的数据【关联t_login的id】
        User user = new User();
        user.setCreateTime(new Date().getTime());
        user.setPhone(userDto.getMobile());
        user.setNickName("yyds_" + userDto.getMobile());
        user.setSecLevel(0);
        user.setLoginId(loginid);
        long l = BitStatesUtils.addState(BitStatesUtils.OP_REGISTED, BitStatesUtils.OP_ACTIVED);
        long state = BitStatesUtils.addState(l, BitStatesUtils.OP_AUTHED_PHONE);
        user.setBitState(state);
        super.insert(user);
        return user.getId();
    }

    //初始化用户的账户【都是默认值】
    private void createUserAccount(Long userId) {
        UserAccount userAccount = new UserAccount();
        userAccount.setId(userId);
        userAccount.setUsableAmount(new BigDecimal(0));
        userAccount.setFrozenAmount(new BigDecimal(0));
        userAccount.setCreateTime(new Date().getTime());
        userAccountMapper.insert(userAccount);
    }

    private void createUserBaseInfo(Long userId, Integer regChannel) {
        //5.生成t_user_base_info表数据【使用t_user的id】
        UserBaseInfo userBaseInfo = new UserBaseInfo();
        userBaseInfo.setCreateTime(new Date().getTime());
        userBaseInfo.setRegChannel(regChannel);
        baseInfoMapper.insert(userBaseInfo);
    }

    private void checkVerifyCode(UserDto userDto) {
        //1.校验验证码是否正确
        Object o = redisTemplate.opsForValue().get("register:" + userDto.getMobile());
        AssertUtil.isNotNull(o, "验证码已过期");
        String codeInReris = o.toString().split(":")[0];
        AssertUtil.isEqualsTrim(codeInReris, userDto.getSmsCode(), "验证码不正确");
    }


}